﻿Imports System.Text
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Text.Formatting
Imports System.Globalization

Namespace Microsoft.VisualStudio.ImageInsertion
	''' <summary>
	''' Provides a visual element that shows an image in the editor.
	''' </summary>
	Friend Class ImageAdornment
		Private Sub New()
			' Generate an unique ID for the adornment
			Me.Id = String.Format(CultureInfo.InvariantCulture, "[IMG:{0}]", Guid.NewGuid().ToString())
		End Sub

		Friend Sub New(ByVal span As SnapshotSpan, ByVal image As Image)
			Me.New(span, image.Source.Clone())
			Me.VisualElement.Image.Tag = image.Tag
			Me.VisualElement.MoveTo(Canvas.GetLeft(image), Canvas.GetTop(image))
		End Sub

		Friend Sub New(ByVal span As SnapshotSpan, ByVal source As ImageSource)
            Me.New()
			UpdateTrackingSpan(span)

			Me.VisualElement = New EditorImage(source)
			Me.VisualElement.Tag = Me
		End Sub

		Friend Sub New(ByVal textSnapshop As ITextSnapshot, ByVal info As ImageAdornmentInfo, ByVal source As ImageSource)
			Me.New(New SnapshotSpan(textSnapshop, info.Span), source)
			' Use the adornment info to setup the image parameters.
			Me.Id = info.Id
			Me.TextViewLineDelta = New Point(info.TextViewLineDelta.X, info.TextViewLineDelta.Y)
			Canvas.SetLeft(Me.VisualElement, info.Area.X)
			Canvas.SetTop(Me.VisualElement, info.Area.Y)
			Me.VisualElement.Width = info.Area.Width
			Me.VisualElement.Height = info.Area.Height
			Me.VisualElement.Image.Tag = info.Bitmap
		End Sub

		''' <summary>
		''' Gets the visual representation of the adornment.
		''' </summary>
        Friend Property VisualElement As EditorImage

		''' <summary>
		''' Gets the associated span with the image.
		''' </summary>
        Friend Property TrackingSpan As ITrackingSpan

		''' <summary>
		''' Updates the span the image adornment is tracking
		''' </summary>
		''' <param name="line"></param>
		Friend Sub UpdateTrackingSpan(ByVal line As ITextViewLine)
			UpdateTrackingSpan(New SnapshotSpan(line.Start, line.Length))
		End Sub

		''' <summary>
		''' Updates the span the image adornment is tracking
		''' </summary>
		Friend Sub UpdateTrackingSpan(ByVal span As SnapshotSpan)
            Dim spanText = span.GetText()

			' Create a tracking span removing the spaces at the beginning and at the end.
            Dim emptySpacesAtTheBegining = spanText.Length - spanText.TrimStart().Length
			Me.TrackingSpan = span.Snapshot.CreateTrackingSpan(span.Start.Position + emptySpacesAtTheBegining, spanText.Trim().Length, SpanTrackingMode.EdgeExclusive)
		End Sub

		''' <summary>
		''' Gets or sets the difference between the location of the image and the associated span.
		''' </summary>
        Friend Property TextViewLineDelta As Point

		''' <summary>
		''' Gets an unique id of the adornment.
		''' </summary>
        Friend Property Id As String

		''' <summary>
		''' Gets a simpler representation of the adornment information. This can be serialized.
		''' </summary>
        Friend ReadOnly Property Info As ImageAdornmentInfo
            Get
                Return New ImageAdornmentInfo(Me)
            End Get
        End Property

		''' <summary>
		''' Gets or sets the point where the image adornment is being rendered
		''' </summary>
        Friend Property RenderTrackingPoint As ITrackingPoint

		''' <summary>
		''' Returns tru if the line applies to the render target point.
		''' </summary>
		''' <param name="textSnapshot"></param>
		''' <param name="line"></param>
		''' <returns></returns>
		Friend Function ApplyRenderTrackingPoint(ByVal textSnapshot As ITextSnapshot, ByVal line As ITextViewLine) As Boolean
			If RenderTrackingPoint IsNot Nothing Then
                Dim position = RenderTrackingPoint.GetPosition(textSnapshot)
				Return line.Start.Position = position
			End If

			Return False
		End Function
	End Class
End Namespace